﻿#include <vector>
#include <string>
#include <iostream>
#include <memory>
#include <iomanip>

using namespace std;

//基础物品类，所有商店物品的基类
class StoreItem {
public:
    StoreItem(const std::string& itemName, const std::string& description, int price)
        : name(itemName), description(description), price(price) {}

    virtual ~StoreItem() = default;

    //获取物品名称
    std::string getName() const {
        return name;
    }

    //获取物品描述
    std::string getDescription() const {
        return description;
    }

    //获取物品价格
    int getPrice() const {
        return price;
    }

    //显示物品详情
    virtual void displayDetails() const {
        std::cout << std::left << std::setw(25) << name
            << std::setw(15) << price << "金币"
            << description << std::endl;
    }

protected:
    std::string name;        //名称
    std::string description; //描述
    int price;               //价格
};

//消耗品基类（红瓶、蓝瓶、熏香）
class Consumable : public StoreItem {
public:
    Consumable(const std::string& itemName, const std::string& description,
        int price, int effectValue)
        : StoreItem(itemName, description, price), effectValue(effectValue) {}

    //获取效果值
    int getEffectValue() const {
        return effectValue;
    }

    void displayDetails() const override {
        StoreItem::displayDetails();
    }

private:
    int effectValue;//效果值
};

//饰品基类
class Accessory : public StoreItem {
public:
    Accessory(const std::string& itemName, const std::string& description,
        int price, int boostValue)
        : StoreItem(itemName, description, price), boostValue(boostValue) {}

    //获取提升值
    int getBoostValue() const {
        return boostValue;
    }

    void displayDetails() const override {
        StoreItem::displayDetails();
    }

protected:
    int boostValue;//提升值
};

//红瓶
class HealthPotion : public Consumable {
public:
    HealthPotion(const std::string& itemName, int effectValue, int price)
        : Consumable(itemName, "恢复" + std::to_string(effectValue) + "点生命值",
            price, effectValue) {}
};

//蓝瓶
class ManaPotion : public Consumable {
public:
    ManaPotion(const std::string& itemName, int effectValue, int price)
        : Consumable(itemName, "恢复" + std::to_string(effectValue) + "点法力值",
            price, effectValue) {}
};

//熏香
class Incense : public Consumable {
public:
    Incense(const std::string& itemName, int effectValue, int price)
        : Consumable(itemName, "恢复" + std::to_string(effectValue) + "点理智值",
            price, effectValue) {}
};

//幸运饰品
class LuckAccessory : public Accessory {
public:
    LuckAccessory(const std::string& itemName, int boostValue, int price)
        : Accessory(itemName, "幸运+" + std::to_string(boostValue), price, boostValue) {}
};

//准确度饰品
class AccuracyAccessory : public Accessory {
public:
    AccuracyAccessory(const std::string& itemName, int boostValue, int price)
        : Accessory(itemName, "准确度+" + std::to_string(boostValue), price, boostValue) {}
};

//躲避饰品
class DodgeAccessory : public Accessory {
public:
    DodgeAccessory(const std::string& itemName, int boostValue, int price)
        : Accessory(itemName, "躲避+" + std::to_string(boostValue), price, boostValue) {}
};

//敏捷饰品
class AgilityAccessory : public Accessory {
public:
    AgilityAccessory(const std::string& itemName, int boostValue, int price)
        : Accessory(itemName, "敏捷+" + std::to_string(boostValue), price, boostValue) {}
};

//装备子类：鞋子
class Shoe : public Accessory {
public:
    Shoe(const std::string& itemName, const std::string& boostType, int boostValue, int price)
        : Accessory(itemName, boostType + "+" + std::to_string(boostValue), price, boostValue),
        boostType(boostType) {}
    void displayDetails() const override {
        std::cout << std::left << std::setw(25) << name
            << std::setw(15) << getPrice() << "金币"
            << boostType << " +" << getBoostValue() << std::endl;
    }
private:
    std::string boostType;
};

//头盔
class Helmet : public Accessory {
public:
    Helmet(const std::string& itemName, const std::string& boostType, int boostValue, int price)
        : Accessory(itemName, boostType + "+" + std::to_string(boostValue), price, boostValue),
        boostType(boostType) {}
    void displayDetails() const override {
        std::cout << std::left << std::setw(25) << name
            << std::setw(15) << getPrice() << "金币"
            << boostType << " +" << getBoostValue() << std::endl;
    }
private:
    std::string boostType;
};

//武器
class Weapon : public Accessory {
public:
    Weapon(const std::string& itemName, const std::string& boostType, int boostValue, int price)
        : Accessory(itemName, boostType + "+" + std::to_string(boostValue), price, boostValue),
        boostType(boostType) {}
    void displayDetails() const override {
        std::cout << std::left << std::setw(25) << name
            << std::setw(15) << getPrice() << "金币"
            << boostType << " +" << getBoostValue() << std::endl;
    }
private:
    std::string boostType;
};

//防具
class Armor : public Accessory {
public:
    Armor(const std::string& itemName, const std::string& boostType, int boostValue, int price)
        : Accessory(itemName, boostType + "+" + std::to_string(boostValue), price, boostValue),
        boostType(boostType) {}
    void displayDetails() const override {
        std::cout << std::left << std::setw(25) << name
            << std::setw(15) << getPrice() << "金币"
            << boostType << " +" << getBoostValue() << std::endl;
    }
private:
    std::string boostType;
};

//商店
class Store {
public:
    Store() {
        initializeInventory();
    }

    //初始化商品库存
    void initializeInventory() {
        //生命药水
        addItem(std::make_unique<HealthPotion>("凝痂血菇", 15, 25));
        addItem(std::make_unique<HealthPotion>("地穴蛞蝓粘液", 30, 50));
        addItem(std::make_unique<HealthPotion>("活体肉瘤萃取物", 50, 100));
        //法力药水
        addItem(std::make_unique<ManaPotion>("苔藓脑质", 10, 20));
        addItem(std::make_unique<ManaPotion>("垂涎者脊髓液", 25, 45));
        addItem(std::make_unique<ManaPotion>("沉睡巢母脑脊液", 40, 80));
        //熏香
        addItem(std::make_unique<Incense>("鼠尾草与劣梦混合物", 10, 30));
        addItem(std::make_unique<Incense>("拾荒者安宁粉尘", 20, 55));
        addItem(std::make_unique<Incense>("哑巴僧侣的静默", 35, 90));
        //幸运饰品
        addItem(std::make_unique<LuckAccessory>("污秽的骰子", 5, 40));
        addItem(std::make_unique<LuckAccessory>("四趾兔脚", 8, 70));
        //准确度饰品
        addItem(std::make_unique<AccuracyAccessory>("磨制的凝视之眼", 5, 45));
        addItem(std::make_unique<AccuracyAccessory>("校准的指南腺体", 10, 85));
        //躲避饰品
        addItem(std::make_unique<DodgeAccessory>("褪色的潜行蜥蜴皮", 5, 40));
        addItem(std::make_unique<DodgeAccessory>("无声蝙蝠的耳骨", 8, 75));
        //敏捷饰品
        addItem(std::make_unique<AgilityAccessory>("肌腱编织指环", 5, 42));
        addItem(std::make_unique<AgilityAccessory>("焦躁地精的趾环", 8, 78));
        //鞋子
        addItem(std::make_unique<Shoe>("杂斑猎犬皮便鞋", "敏捷", 10, 60));
        addItem(std::make_unique<Shoe>("无声鼹鼠皮靴", "躲避", 15, 85));
        addItem(std::make_unique<Shoe>("剥制潜地兽胫甲", "敏捷", 20, 120));
        //头盔
        addItem(std::make_unique<Helmet>("锈蚀的铁皮头罩", "力量", 10, 65));
        addItem(std::make_unique<Helmet>("缝合知识兜帽", "智力", 15, 90));
        addItem(std::make_unique<Helmet>("镶嵌复眼的窥视盔", "准确度", 20, 130));
        //武器
        addItem(std::make_unique<Weapon>("碎骨者（粗大胫骨）", "力量", 15, 100));
        addItem(std::make_unique<Weapon>("精准刺管（某种生物毒刺）", "准确度", 25, 150));
        addItem(std::make_unique<Weapon>("掘洞巫婆的搅杖", "智力", 30, 180));
        //防具
        addItem(std::make_unique<Armor>("废料与骨片拼合盾", "躲避", 15, 110));
        addItem(std::make_unique<Armor>("硬化甲壳胸甲", "力量", 20, 140));
        addItem(std::make_unique<Armor>("苦修者的刺猬披肩", "理智", 25, 160));
    }

    //添加商品到库存
    void addItem(std::unique_ptr<StoreItem> item) {
        inventory.push_back(std::move(item));
    }

    //显示所有商品
    void displayInventory() const {
        std::cout << "\n===== 商店库存 =====" << std::endl;
        std::cout << std::left << std::setw(5) << "编号"
            << std::setw(25) << "物品名称"
            << std::setw(15) << "价格"
            << "效果" << std::endl;
        std::cout << std::string(65, '-') << std::endl;

        for (int i = 0; i < inventory.size(); i++) {
            std::cout << std::setw(5) << (i + 1);
            inventory[i]->displayDetails();
        }
    }

    //购买商品
    bool purchaseItem(int index, int& playerMoney) {
        if (index < 0 || index >= static_cast<int>(inventory.size())) {
            std::cout << "无效的商品编号！" << std::endl;
            return false;
        }

        const int itemPrice = inventory[index]->getPrice();
        if (playerMoney < itemPrice) {
            std::cout << "金币不足，无法购买 " << inventory[index]->getName() << "！" << std::endl;
            return false;
        }

        playerMoney -= itemPrice;
        std::cout << "成功购买 " << inventory[index]->getName()
            << "，花费 " << itemPrice << " 金币！" << std::endl;

        //从商店移除已购买的商品
        inventory.erase(inventory.begin() + index);
        return true;
    }

private:
    std::vector<std::unique_ptr<StoreItem>> inventory; //商品库存
};

int main() {
    Store darkShop;
    int playerGold = 300;

    darkShop.displayInventory();

    std::cout << "\n购买物品测试：" << std::endl;
    darkShop.purchaseItem(0, playerGold); // 购买第一个商品
    darkShop.purchaseItem(5, playerGold); // 购买第六个商品

    std::cout << "\n购买后库存：" << std::endl;
    darkShop.displayInventory();
    std::cout << "玩家剩余金币: " << playerGold << std::endl;

    return 0;
}